﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;

namespace DBProvider.Providers
{
	public class UserProvider : IUserProvider
	{
		#region IUserProvider Members

		public User CreateUser(User theNewUser, out string msg)
		{
			if(theNewUser == null)
			{
				throw new ArgumentNullException();
			}

			User result = null;
			msg = string.Empty;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var isExist = db.Users.Count(u => u.UserName == theNewUser.UserName) > 0;

					if(isExist)
					{
						msg = "用户名已存在";
					}
					else
					{
						result = new User()
						{
							Address = theNewUser.Address,
							Birthdate = theNewUser.Birthdate,
							Email = theNewUser.Email,
							Fax = theNewUser.Fax,
							GroupID = theNewUser.GroupID,
							IsAdmin = theNewUser.IsAdmin,
							MSN = theNewUser.MSN,
							PhoneNumber = theNewUser.PhoneNumber,
							Picture = theNewUser.Picture,
							QQ = theNewUser.QQ,
							Remark = theNewUser.Remark,
							SecretAnswer1 = theNewUser.SecretAnswer1,
							SecretAnswer2 = theNewUser.SecretAnswer2,
							SecretQuestion1 = theNewUser.SecretQuestion1,
							SecretQuestion2 = theNewUser.SecretQuestion2,
							Sex = theNewUser.Sex,
							ShengFenZheng = theNewUser.ShengFenZheng,
							Telephone = theNewUser.Telephone,
							UserCName = theNewUser.UserCName,
							UserName = theNewUser.UserName,
							UserState = theNewUser.UserState,
							ZipCode = theNewUser.ZipCode,
							StateProvinceID = theNewUser.StateProvinceID,
							CityID = theNewUser.CityID,
							UnitName = theNewUser.UnitName,
							Position = theNewUser.Position,
							RoleID = theNewUser.RoleID,
							DrugStoreID = theNewUser.DrugStoreID,
							Credits = theNewUser.Credits,
							AddDate = theNewUser.AddDate
						};

						result.UserPassword = CommonHelper.Encrypt(theNewUser.UserPassword);

						db.Users.InsertOnSubmit(result);
						db.SubmitChanges();

						result = db.Users.SingleOrDefault(u => u.UserName == theNewUser.UserName);
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public bool DeleteUser(int userID)
		{
			if(userID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			var result = false;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var submit = false;

					var rltUserAndActivity = from ua in db.RLT_ACTIVITYANDUSERs
																	 where ua.userID == userID
																	 select ua;

					if(rltUserAndActivity != null)
					{
						db.RLT_ACTIVITYANDUSERs.DeleteAllOnSubmit(rltUserAndActivity);

						submit = true;
					}

					var activity = from a in db.Activities
												 where a.ActivityInitiator == userID
												 select a;

					if(activity != null)
					{
						db.Activities.DeleteAllOnSubmit(activity);

						submit = true;
					}

					var rltUserAndCourse = from uc in db.RLT_USERANDCOURCEs
																 where uc.UserID == userID
																 select uc;

					if(rltUserAndCourse != null)
					{
						db.RLT_USERANDCOURCEs.DeleteAllOnSubmit(rltUserAndCourse);

						submit = true;
					}

					var rltUserAndExaminationAnswer = from uea in db.RLT_USERANDExaminationAnswers
																						where uea.UserID == userID
																						select uea;

					if(rltUserAndExaminationAnswer != null)
					{
						db.RLT_USERANDExaminationAnswers.DeleteAllOnSubmit(rltUserAndExaminationAnswer);

						submit = true;
					}

					var rltUserAndExamination = from ue in db.RLT_UserAndExaminations
																			where ue.UserID == userID
																			select ue;

					if(rltUserAndExamination != null)
					{
						db.RLT_UserAndExaminations.DeleteAllOnSubmit(rltUserAndExamination);

						submit = true;
					}

					var answer = from a in db.Answers
											 where a.AnswerUserID == userID
											 select a;

					if(answer != null)
					{
						db.Answers.DeleteAllOnSubmit(answer);

						submit = true;
					}

					var question = from q in db.Questions
												 where q.QuestionUserID == userID
												 select q;

					if(question != null)
					{
						db.Questions.DeleteAllOnSubmit(question);

						submit = true;
					}

					var surveyAnswer = from sa in db.SurveyAnswers
														 where sa.SurveyAnswerUserID == userID
														 select sa;

					if(surveyAnswer != null)
					{
						db.SurveyAnswers.DeleteAllOnSubmit(surveyAnswer);

						submit = true;
					}

					var video = from v in db.Videos
											where v.VideoUserID == userID
											select v;

					if(video != null)
					{
						db.Videos.DeleteAllOnSubmit(video);

						submit = true;
					}

					var dbUser = db.Users.SingleOrDefault(u => u.UserID == userID);

					if(dbUser != null)
					{
						db.Users.DeleteOnSubmit(dbUser);

						submit = true;
					}

					var dbQQID = db.QQIDs.SingleOrDefault(qq => qq.QQID1.Equals(dbUser.QQ));

					if(dbQQID != null)
					{
						db.QQIDs.DeleteOnSubmit(dbQQID);
						submit = true;
					}

					if(submit)
					{
						db.SubmitChanges();

						result = true;
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public bool UpdateUser(User u, bool setPwd)
		{
			if(u == null || u.UserID <= 0)
			{
				throw new ArgumentException();
			}

			var result = false;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var dbUser = db.Users.SingleOrDefault(user => user.UserID == u.UserID);

					if(dbUser != null)
					{
						dbUser.Address = u.Address;
						dbUser.Birthdate = u.Birthdate;
						dbUser.Email = u.Email;
						dbUser.Fax = u.Fax;
						dbUser.GroupID = u.GroupID;
						dbUser.IsAdmin = u.IsAdmin;
						dbUser.MSN = u.MSN;
						dbUser.PhoneNumber = u.PhoneNumber;
						dbUser.Picture = u.Picture;
						dbUser.QQ = u.QQ;
						dbUser.Remark = u.Remark;
						dbUser.SecretAnswer1 = u.SecretAnswer1;
						dbUser.SecretAnswer2 = u.SecretAnswer2;
						dbUser.SecretQuestion1 = u.SecretQuestion1;
						dbUser.SecretQuestion2 = u.SecretQuestion2;
						dbUser.Sex = u.Sex;
						dbUser.ShengFenZheng = u.ShengFenZheng;
						dbUser.Telephone = u.Telephone;
						dbUser.UserCName = u.UserCName;
						dbUser.UserName = u.UserName;
						dbUser.UserState = u.UserState;
						dbUser.ZipCode = u.ZipCode;
						if(setPwd)
						{
							dbUser.UserPassword = CommonHelper.Encrypt(u.UserPassword);
						}

						dbUser.StateProvinceID = u.StateProvinceID;
						dbUser.CityID = u.CityID;
						dbUser.Credits = u.Credits;
						dbUser.Position = u.Position;
						dbUser.UnitName = u.UnitName;
						dbUser.RoleID = u.RoleID;
						dbUser.LastUpdateTime = u.LastUpdateTime;

						db.SubmitChanges();

						result = true;
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public User GetUser(int userID, bool loadRelation)
		{
			if(userID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			User result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					if(loadRelation)
					{
						DataLoadOptions dlo = new DataLoadOptions();
						dlo.LoadWith<User>(u => u.Role);
						dlo.LoadWith<User>(u => u.StateProvince);
						dlo.LoadWith<User>(u => u.City);
						dlo.LoadWith<User>(u => u.DrugStore);
						db.LoadOptions = dlo;
					}

					result = db.Users.SingleOrDefault(u => u.UserID == userID);

					if(result != null)
					{
						result.UserPassword = CommonHelper.Decrypt(result.UserPassword);
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public User GetUser(string userName)
		{
			if(string.IsNullOrEmpty(userName))
			{
				throw new ArgumentException();
			}

			User result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					DataLoadOptions dlo = new DataLoadOptions();
					dlo.LoadWith<User>(q => q.Role);
					db.LoadOptions = dlo;

					result = db.Users.SingleOrDefault(u => u.UserName == userName);
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<User> GetAllUser()
		{
			List<User> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var data = db.Users;

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<User> GetAllUser(int pageIndex, int pageSize, out int totalRecords)
		{
			List<User> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					totalRecords = db.Users.Count();
					var data = db.Users.Skip(pageIndex * pageSize).Take(pageSize);

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<User> GetUserByGroup(int groupID)
		{
			if(groupID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<User> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var data = db.Users.Where(u => u.GroupID == groupID);

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<User> GetUserByGroup(int groupID, int pageIndex, int pageSize, out int totalRecords)
		{
			if(groupID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<User> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					totalRecords = db.Users.Count(u => u.GroupID == groupID);
					var data = db.Users.Where(u => u.GroupID == groupID).Skip(pageIndex * pageSize).Take(pageSize);

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public bool ValidUser(string userName, string pwd, out string msg)
		{
			if(string.IsNullOrEmpty(userName))
			{
				throw new ArgumentException();
			}

			var result = false;
			msg = string.Empty;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var dbUser = db.Users.SingleOrDefault(u => u.UserName == userName);

					if(dbUser == null)
					{
						msg = "用户名不存在";
					}
					else
					{
						if(dbUser.UserState == (int)UserState.Deleted)
						{
							msg = "用户无效,已删除";
						}
						else
						{
							var encipedPwd = CommonHelper.Encrypt(pwd);

							if(encipedPwd == dbUser.UserPassword)
							{
								result = true;
							}
						}
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public bool ResetPassword(User theUser)
		{
			if(theUser == null || theUser.UserID <= 0)
			{
				throw new ArgumentException();
			}

			var result = false;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var dbUser = db.Users.SingleOrDefault(u => u.UserID == theUser.UserID);

					if(dbUser != null)
					{
						dbUser.SecretAnswer1 = theUser.SecretAnswer1;
						dbUser.SecretAnswer2 = theUser.SecretAnswer2;
						dbUser.SecretQuestion1 = theUser.SecretQuestion1;
						dbUser.SecretQuestion2 = theUser.SecretQuestion2;
						dbUser.UserPassword = CommonHelper.Encrypt(theUser.UserPassword);

						db.SubmitChanges();
						result = true;
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<User> GetUserByRole(string roleName, int drugStoreID)
		{
			if(string.IsNullOrEmpty(roleName))
			{
				throw new ArgumentException("角色名称非法", "roleName");
			}

			List<User> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var role = db.Roles.SingleOrDefault(r => r.RoleName.ToLower() == roleName.ToLower());

					if(role != null)
					{
						if(roleName.ToLower() == "admin")
						{
							var data = db.Users.Where(u => u.RoleID == role.RoleID);

							if(data != null)
							{
								result = data.ToList();
							}
						}
						else if(roleName.ToLower() == "storeadmin")
						{
							var data = from u in db.Users
												 where u.RoleID == role.RoleID
												 select u;

							if(data != null)
							{
								result = data.ToList();
							}
						}
						else if(roleName.ToLower() == "storemember" || roleName.ToLower() == "commonuser")
						{
							var data = from u in db.Users
												 where u.RoleID == role.RoleID && u.DrugStoreID == drugStoreID
												 select u;

							if(data != null)
							{
								result = data.ToList();
							}
						}
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<User> GetUserByDrugStore(int drugStoreID, bool onlyActive)
		{
			if(drugStoreID <= 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<User> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					DataLoadOptions dlo = new DataLoadOptions();
					dlo.LoadWith<User>(q => q.Role);
					db.LoadOptions = dlo;

					IQueryable<User> data = null;

					if(onlyActive)
					{
						data = db.Users.Where(u => u.DrugStoreID == drugStoreID && u.UserState == (int)UserState.Active);
					}
					else
					{
						data = db.Users.Where(u => u.DrugStoreID == drugStoreID);
					}

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public Role GetRole(string roleName)
		{
			if(string.IsNullOrEmpty(roleName))
			{
				throw new ArgumentNullException();
			}

			Role result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					result = db.Roles.SingleOrDefault(r => r.RoleName.ToLower().Equals(roleName));
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<Role> GetAllRole()
		{
			List<Role> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					var data = db.Roles;

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		public List<User> GetUserByDrugStore(int drugStoreID, bool onlyActive, int pageIndex, int pageSize, out int totalRecords)
		{
			if(drugStoreID <= 0 || pageIndex < 0 || pageSize < 0)
			{
				throw new ArgumentOutOfRangeException();
			}

			List<User> result = null;

			try
			{
				using(DBHealthCommunityDataContext db = new DBHealthCommunityDataContext())
				{
					DataLoadOptions dlo = new DataLoadOptions();
					dlo.LoadWith<User>(q => q.Role);
					db.LoadOptions = dlo;

					IQueryable<User> data = null;

					if(onlyActive)
					{
						totalRecords = db.Users.Count(u => u.DrugStoreID == drugStoreID && u.UserState == (int)UserState.Active);
						data = db.Users.Where(u => u.DrugStoreID == drugStoreID && u.UserState == (int)UserState.Active).Skip(pageIndex * pageSize).Take(pageSize);
					}
					else
					{
						totalRecords = db.Users.Count(u => u.DrugStoreID == drugStoreID);
						data = db.Users.Where(u => u.DrugStoreID == drugStoreID).Skip(pageIndex * pageSize).Take(pageSize);
					}

					if(data != null)
					{
						result = data.ToList();
					}
				}
			}
			catch(Exception exc)
			{
				throw exc;
			}

			return result;
		}

		#endregion
	}
}
